﻿using Admin.NET.Core;
using Admin.NET.Core.Service;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MOKA.TPM.Entity;
using MOKA.TPM.Utility;
using MOKA.TPM.Utility.Const;
using Newtonsoft.Json.Linq;
using SqlSugar;
using System.Data;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;

namespace MOKA.TPM.Service;

/// <summary>
/// 系統服務 🧩
/// </summary>
[ApiDescriptionSettings(TPMConst.GroupName, Name = "Service", Order = 305)]
[NonUnify]
public class SystemService : IDynamicApiController, ITransient
{
    private SqlSugarScopeProvider Context;
    private readonly SysCacheService _sysCacheService;

    public SystemService(SysCacheService sysCacheService)
    {
        var iTenant = SqlSugarSetup.ITenant;
        Context = iTenant.GetConnectionScope(TPMConst.MESBaseDB);
        _sysCacheService = sysCacheService;
    }

    [ApiDescriptionSettings(Name = "GetToken"), HttpPost]
    [AllowAnonymous]
    public UserToken GetToken([FromBody] LoginUser user)
    {
        UserToken UToken = new UserToken();
        string md5Pwd = PassEncrypt.MD5Encrypt(user.PassWord);

        string Sql = string.Format("select * from MESBaseDB.dbo.T_USER where UserName='{0}' and pwd='{1}'", user.UserName, md5Pwd);
        DataTable Dt = Context.Ado.GetDataTable(Sql);
        if (Dt.Rows.Count > 0)
        {
            UToken.UserAccount = Dt.Rows[0]["UserName"].ToString();
            UToken.UserName = Dt.Rows[0]["UserRemark"].ToString();
            try
            {
                UToken.UserId = Dt.Rows[0]["UserID"].ToString();
            }
            catch
            {
                UToken.UserId = "-1";
            }

            UToken.Token = PassEncrypt.MD5Encrypt(UToken.UserAccount + user.PassWord + "768");
            UToken.PassWord = user.PassWord;
            UToken.CheckType = user.CheckType;
            UToken.OBAPhase = user.OBAPhase;
            UToken.AppName = user.AppName;//APP名称
            _sysCacheService.Set(UToken.UserAccount, UToken);
        }
        else
        {
            return GetDomainValid(user);
        }
        return UToken;
    }

    /// <summary>
    /// 加入域验证
    /// </summary>
    /// <returns></returns>
    public UserToken GetDomainValid(LoginUser user)
    {
        UserToken UToken = null;
        bool verifyResult = DomainUserVerify.Verify(user.UserName, user.PassWord);
        if (!verifyResult)
        {
            return null;
        }

        string Sql = string.Format("select * from MESBaseDB.dbo.Employee where LoginName='{0}'", user.UserName);
        DataTable Dt = Context.Ado.GetDataTable(Sql);
        if (Dt.Rows.Count > 0)
        {
            UToken = new UserToken();
            UToken.UserAccount = Dt.Rows[0]["LoginName"].ToString();
            UToken.UserName = Dt.Rows[0]["EmployeeName"].ToString();
            try
            {
                UToken.UserId = Dt.Rows[0]["EmployeeNo"].ToString();
            }
            catch
            {
                UToken.UserId = "-1";
            }

            UToken.Token = PassEncrypt.MD5Encrypt(UToken.UserAccount + user.PassWord + "768");
            UToken.PassWord = user.PassWord;
            UToken.CheckType = user.CheckType;
            UToken.OBAPhase = user.OBAPhase;
            UToken.AppName = user.AppName;//APP名称
            _sysCacheService.Set(UToken.UserAccount, UToken);
        }
        else
        {
            UToken = null;
        }
        return UToken;
    }

    [ApiDescriptionSettings(Name = "Logout"), HttpPost]
    [AllowAnonymous]
    public CommonResult Logout(dynamic obj)
    {
        CommonResult result = new CommonResult();
        try
        {
            string userId = obj.userId;
            //增加退出时，所登记的样机检验是否全部检验完了。否则不可退
            string sql = @"SELECT top 1 a.LineName,b.TVSN FROM $OtherDataDBName.dbo.OBAStationInfo a WITH(NOLOCK)
                               INNER JOIN $OtherDataDBName.dbo.OBAStationInfoDetail b WITH(NOLOCK) ON a.Id = b.ParentId
                               WHERE a.UserId = '{0}';";
            sql = string.Format(sql, userId);
            DataSet ds = Context.Ado.GetDataSetAll(sql);
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                DataRow dr = ds.Tables[0].Rows[0];
                string error = dr["LineName"].ToString() + "【" + dr["TVSN"].ToString() + "】\r\n未检验完，不可退出\r\nIncomplete inspection, cannot exit!";
                result.Result = false;
                result.Error = error;
            }
            else
            {
                sql = "delete from $OtherDataDBName.dbo.OBAStationInfo where userId='{0}'";
                sql = string.Format(sql, userId);
                Context.Ado.ExecuteCommand(sql);
                result.Result = true;
                result.Error = "";
            }
        }
        catch (Exception ex)
        {
            result.Result = false;
            result.Error = ex.ToString();
        }
        return result;
    }

    /// <summary>
    /// 检查用户是否有OBA操作权限，如果有，登录界面需要显示阶段或者（在线或在室)
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "CheckUserOBARight"), HttpPost]
    [AllowAnonymous]
    public CommonResult CheckUserOBARight(dynamic obj)
    {
        CommonResult result = new CommonResult();
        try
        {
            //增加退出时，所登记的样机检验是否全部检验完了。否则不可退
            string sql = @"SELECT * FROM MESBaseDB.dbo.WebUserRoles WHERE UserNo='{0}' and RoleId='Quality_OQA'";
            sql = string.Format(sql, obj.UserNo);
            DataSet ds = Context.Ado.GetDataSetAll(sql);
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                result.Result = true;
            }
            else
            {
                result.Result = false;
            }
        }
        catch (Exception ex)
        {
            result.Result = false;
            result.Error = ex.ToString();
        }
        return result;
    }

    [HttpGet]
    [AllowAnonymous]
    public IsUpdate CheckUpdate([FromQuery] string ClientVersion)
    {
        IsUpdate isU = new IsUpdate();
        var clientVersions = ClientVersion.Split('|');
        string AppName = clientVersions.Length < 2 ? "ApiCloud" : "TPM";
        string Sql = "Select top 1 [Version],[Source],CONVERT(varchar(16), [UpdateDate],120) [UpdateDate] from [MESBaseDB].[dbo].[AppVersion] with(nolock) where AppName='" + AppName + "' order by fid desc";
        DataTable Dt = Context.Ado.GetDataTable(Sql);
        Version old_version = new Version(clientVersions.Length < 2 ? ClientVersion : clientVersions[0]);
        Version new_version = new Version(Dt.Rows[0]["Version"].ToString());

        if (new_version != old_version)
        {
            isU.IsUp = true;
            isU.Version = Dt.Rows[0]["Version"].ToString();
            isU.Source = Dt.Rows[0]["Source"].ToString();
            isU.UpdateDate = Dt.Rows[0]["UpdateDate"].ToString();
        }
        else
        {
            isU.IsUp = false;
        }

        return isU;
    }

    [HttpGet]
    [AllowAnonymous]
    public ExsitToken IsExistToken([FromQuery] string UserAccount, [FromQuery] string Token, [FromQuery] string PassWord)
    {
        ExsitToken Cs = new ExsitToken();
        string md5Pwd = PassEncrypt.MD5Encrypt(PassWord);
        string Sql = string.Format("select * from MESBaseDB.dbo.T_USER where UserName='{0}' and PWD='{1}'", UserAccount, md5Pwd);
        DataTable Dt = Context.Ado.GetDataTable(Sql);
        if (Dt.Rows.Count > 0)
        {
            Cs.Rs = true;
        }
        else
        {
            Cs = null;
        }

        return Cs;
    }

    #region 域验证类 Add By 罗敬淮 2017-10-17

    public class DomainUserVerify
    {
        private static int LOGon32_LOGon_INTERACTIVE = 2;
        private static int LOGon32_PROVIDER_DEFAULT = 0;
        private static IntPtr tokenHandle = new IntPtr(0);

        [DllImport("advapi32.dll")]
        private static extern bool LogonUser(string lpszUsername,
            string lpszDomain,
            string lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);

        public static bool Verify(string userName, string pwd, string domain = "TCLKING")
        {
            bool boolResult = false;
            tokenHandle = IntPtr.Zero;
            //使用域密码登录
            // boolResult = LogonUser(userName, domain, pwd, LOGon32_LOGon_INTERACTIVE, LOGon32_PROVIDER_DEFAULT, ref tokenHandle);

            try
            {
                JObject job = OALoginCheck(userName, pwd);
                if (job.Value<string>("success").ToLower() == "true")  //验证成功
                {
                    boolResult = true;
                }
            }
            catch
            {
            }

            return boolResult;
        }

        private static JObject OALoginCheck(string UserAcc, string Pwd)
        {
            string url = "http://login.tcl.com/siam/rest/auth/authenticate";
            //定义request并设置request的路径

            WebRequest request = WebRequest.Create(url);
            request.Method = "post";
            //初始化request参数
            string postData = "{username: \"" + UserAcc + "\", password:\"" + Pwd.Replace(@"\", @"\\") + "\" }";
            //设置参数的编码格式，解决中文乱码
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            //设置request的MIME类型及内容长度
            request.ContentType = "application/json";
            request.ContentLength = byteArray.Length;

            string Rstr = RandomStringUtils.random(10, true, true);
            string Times = DateTime.Now.ToString("yyyyMMddHHmmss") + "Z";
            string encodekey = Md5Helper.Md256Hex("tmt_oa" + Rstr + Times + "{2sd4TeSkdADee24C}");
            string sign = Md5Helper.Md5Hex(postData + "&2sd4TeSkdADee24C").ToUpper();
            string appinfo = "app - demo";
            request.Headers.Add("appuser", "tmt_oa");
            request.Headers.Add("randomcode", Rstr);
            request.Headers.Add("timestamp", Times);
            request.Headers.Add("encodekey", encodekey);
            request.Headers.Add("sign", sign);
            request.Headers.Add("appinfo", appinfo);

            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();
            //定义response为前面的request响应
            WebResponse response = request.GetResponse();
            //获取相应的状态代码
            //定义response字符流
            dataStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            string restr = reader.ReadToEnd();//读取所有
            JObject ob = JsonHelper.ToJObject(restr);
            return ob;
        }
    }

    #endregion 域验证类 Add By 罗敬淮 2017-10-17
}